import {
  Directive,
  Input,
  OnChanges,
  SimpleChanges,
  HostBinding,
  ElementRef,
  Renderer2,
  HostListener,
} from '@angular/core';
import { makeLoadingIcon } from '../loading/loading-icon';
import { makeIcon } from './icon-maker';

@Directive({
  selector: '[fuiBtn]',
})
export class BtnDirective implements OnChanges {
  @HostBinding('class.fui-btn') hostClass = true;

  /** Button type. */
  @Input() fuiBtn: 'primary' | 'default' | 'danger' | 'warning' | 'success';

  /** Button size, default to 'md' if not set. */
  @Input() set size(size: 'sm' | 'md' | 'lg') {
    const classList = this.el.nativeElement.classList;
    ['sm', 'md', 'lg'].forEach((_size) => {
      if (classList.contains(`fui-btn-${_size}`)) {
        classList.remove(`fui-btn-${_size}`);
      }
    });
    this.el.nativeElement.classList.add(`fui-btn-${size}`);
  }

  /** Button icon name, optional. */
  @Input() set fuiBtnIcon(iconName: string) {
    const nativeElement = this.el.nativeElement;
    if (this.icon) {
      this.renderer.removeChild(nativeElement, this.icon);
    }
    this.icon = makeIcon(iconName);
    this.icon.classList.add('fui-btn-icon-left');
    this.renderer.insertBefore(nativeElement, this.icon, nativeElement.childNodes[0]);
  }

  /** Add loading state to button if set true. */
  @Input() set fuiBtnLoading(loading: boolean) {
    const nativeElement = this.el.nativeElement;

    if (!loading) {
      this.renderer.removeChild(nativeElement, this.loadingIcon);
      nativeElement.classList.remove('fui-btn-loading');
      return ;
    }

    nativeElement.classList.add('fui-btn-loading');
    if (nativeElement.childNodes.length > 0) {
      this.renderer.insertBefore(nativeElement, this.loadingIcon, nativeElement.childNodes[0]);
    } else {
      this.renderer.appendChild(nativeElement, this.loadingIcon);
    }
  }

  loadingIcon: SVGSVGElement = makeLoadingIcon();
  icon: SVGSVGElement;

  @HostListener('click', ['$event'])
  onClick($event): void {
    this.addBtnRippleCircle($event);
  }

  constructor(private el: ElementRef, private renderer: Renderer2) {
    this.el.nativeElement.classList.add('fui-btn-md');
    this.loadingIcon.classList.add('fui-btn-icon-left');
  }

  ngOnChanges(changes: SimpleChanges) {
    const {fuiBtn: fuiBtnChange} = changes;
    if (fuiBtnChange && fuiBtnChange.currentValue) {
      this.el.nativeElement.classList.add(`fui-btn-${fuiBtnChange.currentValue}`);
    }
  }

  addBtnRippleCircle($event) {
    const btnRippleCircle = document.createElement('span');
    this.renderer.addClass(btnRippleCircle, 'fui-btn-ripple-circle');
    this.renderer.addClass(btnRippleCircle, 'fui-btn-ripple-circle-color');
    this.renderer.setStyle(btnRippleCircle, 'top', $event.offsetY + 'px');
    this.renderer.setStyle(btnRippleCircle, 'left', $event.offsetX + 'px');
    this.renderer.appendChild(this.el.nativeElement, btnRippleCircle);
    setTimeout(() => {
      this.renderer.removeChild(this.el.nativeElement, btnRippleCircle);
    }, 500);
  }
}
